package com.pxmeta.app.controller.game;

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.hutool.core.collection.CollectionUtil;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.pxmeta.circle.entity.Circle;
import com.pxmeta.circle.service.IUserCircleService;
import com.pxmeta.common.constant.HttpStatus;
import com.pxmeta.common.core.domain.AjaxResult;
import com.pxmeta.common.core.redis.RedisCache;
import com.pxmeta.common.utils.SecurityUtils;
import com.pxmeta.user.entity.User;
import com.pxmeta.user.service.IUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;

@RestController
@Api(value = "聊天匹配",tags = "聊天匹配")
@RequiredArgsConstructor
@Slf4j
public class ChatMatchingController {

    private final RedisCache redisCache;

    public static final String MATCHING_KEY = "matching_user_ids";

    private final IUserService userService;

    private final IUserCircleService userCircleService;


    @GetMapping("/getMatchingCount")
    @ApiOperation("获取剩余匹配次数")
    public AjaxResult getMatchingCount(){
        Long userId = SecurityUtils.getUserId();
        int day = LocalDateTime.now().getDayOfMonth();
        String key = String.format("chat_match_count_%s_%s",day,userId);
        Integer count = redisCache.getCacheObject(key);
        if (null == count){
            count = 15;
        }

        Map<String, Object> map = Maps.newHashMap();
        map.put("count", count);

        return AjaxResult.success(map);
    }


    /**
     * 聊天匹配
     * @return
     */
    @GetMapping("/chatMatching")
    @SaCheckLogin
    @ApiOperation("聊天匹配")
    public AjaxResult chatMatching(){
        Long userId = SecurityUtils.getUserId();
        int day = LocalDateTime.now().getDayOfMonth();
        String key = String.format("chat_match_count_%s_%s",day,userId);

        //判断今日匹配次数是否达到上限，15次以上。

        Integer count = redisCache.getCacheObject(key);
        log.info("开始进入聊天匹配，用户id: {}, 剩余次数：{}",userId, count);
        if (null == count ){
            redisCache.setCacheObject(key,15,1, TimeUnit.DAYS);
        }else {
            if (count <= 0){
                return AjaxResult.error("今日匹配次数已经达到上限！");
            }
            count --;
            redisCache.setCacheObject(key,count,1, TimeUnit.DAYS);
        }

        //1. 优先匹配异性，年龄相差 8 岁以内，且也正在匹配中的用户。
        //2. 如果 1 没有，则匹配异性且正在匹配的用户。
        //3. 如果 2 没有，则匹配异性、年龄相差 8 岁以内、具有相同兴趣圈子且在线用户。
        //4. 如果 3 没有，则匹配异性、年龄相差 8 岁以内、且在线的用户。
        //5. 如果 4 没有，则匹配异性在线用户。
        //6. 如果 5 没有，则匹配异性、具有相同兴趣圈子的用户。

        //查找正在匹配的用户列表
        Set<Long> cacheSet = redisCache.getCacheSet(MATCHING_KEY);

        //当前用户
        User currentUser = userService.getById(userId);
        LocalDate birthday = currentUser.getBirthday();
        if (null == birthday){
            return AjaxResult.error(HttpStatus.PARAMS_ERROR,"请设置您的生日!");
        }
        int currentUserYear = birthday.getYear();

        if (CollectionUtil.isEmpty(cacheSet)){
            cacheSet = Sets.newHashSet();
            //加入正在匹配列表中。
            cacheSet.add(userId);
            redisCache.setCacheSet(MATCHING_KEY,cacheSet);
        }else {
            //加入正在匹配列表中。
            cacheSet.add(userId);
            redisCache.setCacheSet(MATCHING_KEY,cacheSet);
            //正在匹配的用户列表。
            List<User> users = userService.listByIds(cacheSet);
            User matchingUser = null;
            for (User user : users) {
                //移除自己
                if (user.getId().equals(currentUser.getId())){
                    continue;
                }
                LocalDate userBirthday = user.getBirthday();
                Integer sex = user.getSex();
                if (null == userBirthday || (null != sex && sex.equals(currentUser.getSex()))){
                    continue;
                }
                int userYear = userBirthday.getYear();
                int yearDiff = currentUserYear - userYear;
                if (yearDiff < 0){
                    yearDiff  =  -yearDiff;
                }

                //匹配成功。
                if (yearDiff<=8){ //优先查找年龄差小于 8 的用户。
                    redisCache.removeCacheSet(MATCHING_KEY,user.getId());
                    redisCache.removeCacheSet(MATCHING_KEY,currentUser.getId());
                    return AjaxResult.success(user);
                }
                //当没有年龄差小于 8 的用户时，则再返回无年龄限制。
                matchingUser = user;
            }
            if (null != matchingUser){
                redisCache.removeCacheSet(MATCHING_KEY,matchingUser.getId());
                redisCache.removeCacheSet(MATCHING_KEY,currentUser.getId());
                return AjaxResult.success(matchingUser);
            }
        }

        //则匹配异性、年龄相差 8 岁以内、具有相同兴趣圈子且在线用户。

        Integer oppositeSex = 0;
        if (currentUser.getSex()==1){
            oppositeSex = 2;
        }else {
            oppositeSex = 1;
        }


        //上述都没有匹配到，随机匹配具有相同兴趣圈子的异性用户。
        List<Circle> userCircle = userCircleService.getUserCircle(userId);
        for (Circle circle : userCircle) {
            if (circle.getId() == 1){
                continue;
            }

            Integer isSystem = circle.getIsSystem();
            if (isSystem == 1){
                Long circleId = circle.getId();
                List<User> circleOppositeUser = userCircleService.getUserListBySex(circleId,oppositeSex);
                if (CollectionUtil.isNotEmpty(circleOppositeUser)){
                    Collections.shuffle(circleOppositeUser);
                    User matchingUser = circleOppositeUser.get(0);
                    redisCache.removeCacheSet(MATCHING_KEY,matchingUser.getId());
                    redisCache.removeCacheSet(MATCHING_KEY,currentUser.getId());
                    return AjaxResult.success(matchingUser);
                }
            }
        }
        List<User> circleOppositeUser = userCircleService.getUserListBySex(1L,oppositeSex);
        if (CollectionUtil.isNotEmpty(circleOppositeUser)){
            Collections.shuffle(circleOppositeUser);
            User matchingUser = circleOppositeUser.get(0);
            redisCache.removeCacheSet(MATCHING_KEY,matchingUser.getId());
            redisCache.removeCacheSet(MATCHING_KEY,currentUser.getId());
            return AjaxResult.success(matchingUser);
        }
        return AjaxResult.error(HttpStatus.DATA_NOT_FOUND_ERROR,"没有匹配到合适的用户！");
    }
}
